The CoolBar control has been made popular by Microsoft Internet Explorer and consists of a collection of bands that can host other controls, typically flat Toolbar, TextBox, and ComboBox controls. Users can resize and move bands at run time using the mouse and can even change their order. A double-click on a band's handle expands the band as much as possible on the row to which it belongs.
The CoolBar control includes a Bands collection, which in turn contains one or more Band objects. Each Band object can work as the container for only one control, and such a contained control is automatically moved and resized when the user moves or resizes the Band container. You can't have a windowless control as a child control for a Band object, but you can place a windowless control in another container control—for example, a PictureBox control—and make the latter a child control of the Band. Similarly, you can't have more than one child control per Band object, but you can place multiple controls inside the child PictureBox. (In this case, you must write the code that resizes the controls inside the PictureBox's Resize event.)
The CoolBar control is the only control contained in the ComCt332.ocx file. Visual Basic 6 is the first version that includes this control, even though the control has been available to Visual Basic 5 programmers for downloading from the Microsoft site.
The CoolBar control is complex and exposes so many design-time properties that you'll probably need some time to master all of them.
After you drop a CoolBar control on a form, first align it to the form's border. You do this in the regular Properties window by setting the Align property to the value 1-vbAlignTop. All the other design-time properties can be modified within the custom Properties dialog box.
The Orientation property lets you set the aspect of the control to either 0cc3OrientationHorizonal (the default value) or 1-cc3OrientationVertical. The BandBorders property can be set to False if you want to suppress the horizontal lines that mark the borders of each Band, but in most cases it's a better idea to leave it set to True.
Users can move and resize a Band object at run time by dragging its leftmost border, but you can ensure that users aren't allowed to alter the order of Band objects by setting the FixedOrder property to True. The VariantHeight Boolean property tells whether Band objects can have different heights: If True (the default value), the height of each row is determined by the largest MinHeight property of all the Band objects in that row; if False, all rows have the same height, which is determined by the largest MinHeight property of all the Band objects in the CoolBar control.
By default, the CoolBar control has three Band objects, but you can add or remove Band objects in the Bands tab of the Property Pages dialog box, shown in Figure 11-8. Each Band can be resizable (if the Style property is 0cc3BandNormal) or not (if Style is 1cc3BandFixedSize). A band of a fixed width doesn't display the leftmost resize handle.
A Band object can display a string (the Caption property); and it has an initial width (the Width property), a minimal width (MinWidth property), and a minimal height (MinHeight property). It also exposes a Key property, which lets you retrieve the Band object from the Bands collection, and a Tag property, in which you can store any information related to the Band itself.
Figure 11-8. The Bands tab of the Properties dialog box of a CoolBar control. Note that the background picture doesn't work well with a child Toolbar.
The most important property of a Band object is Child, which holds a reference to the child control that's contained in that particular Band. To move a control into a Band object, you must first make the control a child of the CoolBar. The simplest way to do that is by creating it from the Toolbox inside the CoolBar control. After doing that, you'll find the control's name in the list of controls that can be made a child of the Band.
By default, a row of Bands hosts as many Bands as possible, and the position of each Band object depends on the order of Bands and their minimum widths. To change the position of a Band, you can set the NewRow property to True to move a Band to the beginning of the next row. Finally you can set the AllowVertical property to False to make a Band invisible when the CoolBar control changes its orientation to cc3OrientationVertical.
The CoolBar control supports advanced management of colors and pictures. If the Picture property hasn't been assigned, the aspect of the control depends on the standard ForeColor and BackColor properties. If you assign a bitmap or a metafile to the CoolBar's Picture property, this image spreads over all the Bands in the control and the BackColor property is ignored.
To let programmers create a user interface identical to the one exposed by Microsoft Internet Explorer, the CoolBar control includes three additional properties. The EmbossPicture Boolean property determines whether the image should be dithered to two colors; if this property is True, the colors used for embossing depend on the EmbossHighlight and EmbossShadow properties. The CoolBar control uses a dithering algorithm to decide which colors in the original image should be rendered with the lighter or with the darker color.
By default, all Band objects inherit the picture set for the parent CoolBar control and the picture tiles across all the bands regardless of whether the bands are resized or moved. You can set the FixedBackground property of a Band object to False, in which case the image remains fixed when that particular band is moved or resized.
Alternatively, you can set a different image for all or some Band objects by setting their UseCoolBarPicture properties to False and assigning a valid value to their Picture properties. You can even dither the image by setting the affected Bands' EmbossProperty to True and assigning suitable values to the EmbossHighlight and EmbossShadow properties, much as you do with the main CoolBar control.
Band objects also inherit the parent CoolBar's color properties, unless you set the Band's UseCoolBarColors to False. If you do that, you can select the color used for a particular Band by setting its ForeColor and BackColor properties. (But the latter is actually used only if the band doesn't display an image.)
Oddly, neither the CoolBar control nor the Band control expose the Font property, so the appearance of a Band's caption depends entirely on system settings, with the exception of its text color (which is affected by the ForeColor property). For greater control over text attributes, you can use a Label control and put it inside a PictureBox control used as a child control of the CoolBar. (Remember that Label controls and other lightweight controls can't be children of a Band object.)
In most cases, you don't have to interact with a CoolBar control at run time: The CoolBar knows how to resize bands when the user moves them to another row and how to resize child controls inside each band. In a few particular circumstances, however, you might need to programmatically manipulate a CoolBar control.
When the user moves a Band object at run time and this action causes a row of bands to be created or destroyed, the CoolBar control raises a Resize event. You can take advantage of this event if you want to rearrange the position of other controls on the form or to programmatically hide or show Band objects.
But sometimes you shouldn't add code to the Resize event. For example, if the CoolBar control is itself contained in another control, the CoolBar's Height property might return incorrect values if queried from inside that event, or the Resize event might even be suppressed. For these reasons, it's preferable to write code inside the HeightChanged event procedure. This event fires when the Height property of a horizontal CoolBar or the Width property of a vertical CoolBar is modified.
Reacting to such events is important if the form contains other controls. Unless you take precautions, when the CoolBar grows in height other controls on the form might be covered by it. For this reason, you might want to gather all the other controls on the form inside a container control—for example, a PictureBox, so that you can move all of them by simply moving the container. If you follow this approach, you should also write code inside the form's Resize and PictureBox's Resize event procedures. This code snippet (taken from the demonstration program provided on the companion CD and shown in Figure 11-9) illustrates how this solution works:
' Resize the PictureBox when the form resizes. Private Sub Form_Resize() Picture1.Move 0, CoolBar1.Height, ScaleWidth, _ ScaleHeight - CoolBar1.Height End Sub ' Resize and move the PictureBox when the CoolBar's height changes. Private Sub CoolBar1_HeightChanged(ByVal NewHeight As Single) ' Assumes this CoolBar is aligned to the form's top border Picture1.Move 0, NewHeight, ScaleWidth, ScaleHeight - NewHeight End Sub ' Resize the controls inside the PictureBox when the latter is resized. Private Sub Picture1_Resize() Label1.Move 0, 0, Picture1.ScaleWidth, Label1.Height Text1.Move 0, Label1.Height, Picture1.ScaleWidth, _ Picture1.ScaleHeight - Label1.Height End Sub |
Figure 11-9. The demonstration program shows how to deal with resizable CoolBar controls.
From time to time, you might need to programmatically add Band objects at run time. You do this using the Bands collection's Add method, which has the following syntax:
Add([Index],[Key],[Caption],[Image],[NewRow],[Child],[Visible]) As Band |
where each argument affects the Band property of the same name. The Child argument is a reference to the control that should go inside that Band. When you're using this technique for creating a Band object, the child control is probably being created dynamically, in which case you should make it a child of the CoolBar control before assigning it to the Child property of a Band object:
' Create a new ComboBox control. Dim cb As ComboBox Set cb = Controls.Add("VB.ComboBox", "NewCombo") ' Make it a child of the CoolBar1 control. Set cb.Container = CoolBar1 ' Create a new Band object, assigning the ComboBox to its ' Child property. CoolBar1.Bands.Add , "NewBand" , cb.Name, , , cb |
You can remove a Band object using the Bands collection's Remove method:
' Remove the Band object created with the previous code snippet. CoolBar1.Bands.Remove "NewBand" |
While a background image gives the CoolBar control an appealing appearance, you should be aware that it doesn't work well with some types of child controls, most notably Toolbar controls. In fact, the background image doesn't appear inside the Toolbar control, and the end result doesn't look very good. (See Figure 11-9.) Fortunately, there's a workaround, even though it isn't as simple as you might wish.
The solution I found is based on a file that, as I write this, is available on the Visual Studio Owner's Area of the Microsoft Web site, in the CoolBar Sample project. This sample project shows how to include a Toolbar control in the CoolBar control and uses an auxiliary TransTBWrapper module that magically creates a flat toolbar with a transparent background, which you can see in Figure 11-10. This technique was necessary because the version of the Toolbar available on the Web to Visual Basic 5 programmers didn't support the flat style.
As you know, the Visual Basic 6 Toolbar control does support the flat style, so you can embed it in a CoolBar control and still achieve a consistent look. The new Toolbar still doesn't support a transparent background, however, which prevents you from using a background picture in the CoolBar control. It took me some minutes to modify the TransTBWrapper module and have it work with the new Toolbar control, but the results are worth the additional effort. You can use this new version of the module in your own applications, but remember that this file isn't supported by Microsoft.
Figure 11-10. A better version of the demonstration program uses the TransTBWrapper module to host a child Toolbar control with a transparent background.
To achieve the transparent background effect shown in Figure 11-10, prepare your program as you would normally do and then add the TransTB.Ctl file to your project. This file includes the TransTBWrapper ActiveX control, so you can add an instance of this control on the form that contains the CoolBar and Toolbar controls. At this point, you just need a few statements in the form's Load and Unload event procedures:
Private Sub Form_Load() ' Put the toolbar wrapper controls in the CoolBar band. Set TransTBWrapper1.Container = CoolBar1 ' This must be the same Band that hosts the toolbar. Set CoolBar1.Bands(1).Child = TransTBWrapper1 ' Put the toolbar into the toolbar wrapper. Set TransTBWrapper1.Toolbar = Toolbar1 End Sub Private Sub Form_Unload(Cancel As Integer) ' It is VERY important to set the wrapper's Toolbar property ' to Nothing before the form is unloaded. CoolBar1.Visible = False Set TransTBWrapper1.Toolbar = Nothing End Sub |
CAUTION
Ensure that the Form_Unload event is always executed; otherwise, you risk an application crash. For this reason, when testing the application inside the Visual Basic IDE always terminate it by unloading the main form, and never execute an End statement. (An End statement would prevent the Unload event from firing.)
This chapter concludes the description of all the common controls provided with Visual Basic. There are a few other controls that Visual Basic programmers can use in their programs, and these will be described in the next chapter.